<?php

declare(strict_types=1);

namespace App\Core;

use Throwable;

final class ErrorHandler
{
    public static function register(bool $debug): void
    {
        error_reporting(E_ALL);
        ini_set('display_errors', $debug ? '1' : '0');
        ini_set('display_startup_errors', $debug ? '1' : '0');

        set_error_handler(function (int $severity, string $message, string $file = '', int $line = 0): bool {
            // 将错误转换为异常，便于统一处理
            throw new \ErrorException($message, 0, $severity, $file, $line);
        });

        set_exception_handler(function (Throwable $e) use ($debug): void {
            if ($debug) {
                // 调试模式：输出简要错误信息（不输出调用参数）
                http_response_code(500);
                $msg = htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
                $file = htmlspecialchars($e->getFile(), ENT_QUOTES, 'UTF-8');
                $line = (int) $e->getLine();
                echo "Error: {$msg} in {$file}:{$line}";
            } else {
                // 生产模式：记录日志，返回美观错误页
                Logger::error('Unhandled exception: {msg} at {file}:{line}', [
                    'msg' => $e->getMessage(),
                    'file' => $e->getFile(),
                    'line' => (string) $e->getLine(),
                ]);
                http_response_code(500);
                $root = defined('APP_ROOT') ? APP_ROOT : dirname(__DIR__, 2);
                $errorFile = $root . '/templates/errors/500.php';
                if (file_exists($errorFile)) {
                    include $errorFile;
                } else {
                    echo 'Server Error';
                }
            }
        });

        register_shutdown_function(function (): void {
            $err = error_get_last();
            if ($err && in_array($err['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR], true)) {
                // 致命错误兜底
                Logger::error('Fatal error: {msg} at {file}:{line}', [
                    'msg' => (string)($err['message'] ?? ''),
                    'file' => (string)($err['file'] ?? ''),
                    'line' => (string)($err['line'] ?? ''),
                ]);
                http_response_code(500);
                echo 'Server Error';
            }
        });
    }
}
